home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BCI NET
/
BCI NET Dec 94.iso
/
archives
/
programming
/
source
/
fbm12s.lha
/
fbnorm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-18
|
6KB
|
197 lines
/*****************************************************************
* fbnorm.c: FBM Release 1.2 07-Apr-93 Michael Mauldin
*
* Copyright (C) 1989-1993 by Michael Mauldin. Permission is granted
* to use this file in whole or in part for any purpose, educational,
* recreational or commercial, provided that this copyright notice
* is retained unchanged. This software is available to all free of
* charge by anonymous FTP and in the UUNET archives.
*
* fbnorm.c: Normalize contrast and brightness of image
*
* USAGE
* % fbnorm < image > image2
*
* EDITLOG
* LastEditDate = Mon Jun 25 00:03:46 1990 - Michael Mauldin
* LastFileName = /usr2/mlm/src/misc/fbm/fbnorm.c
*
* HISTORY
* 07-Apr-93 Michael Mauldin (mlm) at Carnegie-Mellon University
* Added -J switch
*
* 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
* Package for Release 1.0
*
* 13-Jun-90 Michael Mauldin (mlm) at Carnegie Mellon University
* Final release (version 1.0) mlm@cs.cmu.edu
*
* 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
* Beta release (version 0.9) mlm@cs.cmu.edu
*
* 21-Aug-88 Michael Mauldin (mlm) at Carnegie-Mellon University
* Created.
*****************************************************************/
# include <stdio.h>
# include <math.h>
# include <ctype.h>
# include "fbm.h"
# define USAGE \
"Usage: fbnorm [ -b<val> -w<val> ] [ -<type> ] < image > image"
#ifndef lint
static char *fbmid =
"$FBM fbnorm.c <1.2> 07-Apr-93 (C) 1989-1993 by Michael Mauldin, source \
code available free from MLM@CS.CMU.EDU and from UUNET archives$";
#endif
main (argc, argv)
char *argv[];
{ FBM image;
register unsigned char *bmptr, *tail;
register int j, k, ch, size, cnt;
int min = -1, max = -1, cutoff;
int hist[BYTE];
double blackp = -1.0, whitep = -1.0; /* Percent */
int outtype = FMT_FBM;
/* Get the options */
while (--argc > 0 && (*++argv)[0] == '-')
{ while (*++(*argv))
{ switch (**argv)
{ case 'b': blackp = atof (*argv+1); SKIPARG; break;
case 'w': whitep = atof (*argv+1); SKIPARG; break;
case 'A': outtype = FMT_ATK; break;
case 'B': outtype = FMT_FACE; break;
case 'F': outtype = FMT_FBM; break;
case 'G': outtype = FMT_GIF; break;
case 'I': outtype = FMT_IFF; break;
case 'J': outtype = FMT_JPEG; break;
case 'L': outtype = FMT_LEAF; break;
case 'M': outtype = FMT_MCP; break;
case 'P': outtype = FMT_PBM; break;
case 'R': outtype = FMT_RLE; break;
case 'S': outtype = FMT_SUN; break;
case 'T': outtype = FMT_TIFF; break;
case 'X': outtype = FMT_X11; break;
case 'Z': outtype = FMT_PCX; break;
default: fprintf (stderr, "%s\n", USAGE);
exit (1);
}
}
}
if (argc == 1)
{ blackp = whitep = atof (argv[0]); }
else if (argc == 2)
{ min = atoi (argv[0]); max = atoi (argv[1]); }
else if (argc > 2)
{ fprintf (stderr, "%s\n", USAGE);
exit (1);
}
/* Clear the memory pointer so alloc_fbm won't be confused */
image.cm = image.bm = (unsigned char *) NULL;
/* Now read in the image */
if (read_bitmap (&image, (char *) NULL))
{
/* Check input type */
if (image.hdr.physbits != 8)
{ fprintf (stderr,
"Can't normalize images with %d physical bits per pixel\n",
image.hdr.physbits);
exit (1);
}
if (image.hdr.clrlen > 0)
{ fprintf (stderr,
"Warning, %s\n %s\n",
"normalizing a mapped image is probably not what you want",
"I'll do it anyway, but you should probably use unmap first.");
}
/* Set default tail sizes */
if (image.hdr.planes > 1) /* Color defaults */
{ if (blackp < 0.0) blackp = 0.5;
if (whitep < 0.0) whitep = 0.5;
}
else /* Bw defaults */
{ if (blackp < 0.0) blackp = 2.0;
if (whitep < 0.0) whitep = 1.0;
}
size = image.hdr.rows * image.hdr.cols * image.hdr.planes;
/* Calculate min and max (if not given as arguments) */
if (min < 0 || max < 0)
{
/* Compute histogram */
for (ch=0; ch<BYTE; ch++)
{ hist[ch] = 0; }
for (k=0; k<image.hdr.planes; k++)
{ for (j=0; j< image.hdr.rows; j++)
{ bmptr = &(image.bm[k*image.hdr.plnlen + j*image.hdr.rowlen]);
tail = bmptr + image.hdr.cols;
while (bmptr < tail)
{ hist[*bmptr++]++; }
}
}
/* Take off 'blackp' percent of darkest pixels */
cutoff = size * blackp / 100.0;
for (ch=0, cnt=0; ch<BYTE; ch++)
{ if ((cnt += hist[ch]) > cutoff)
{ min = ch; break; }
}
/* Take off 'whitep' percent of darkest pixels */
cutoff = size * whitep / 100.0;
for (ch = BYTE-1, cnt=0; ch >= 0; ch--)
{ if ((cnt += hist[ch]) > cutoff)
{ max = ch; break; }
}
}
fprintf (stderr, "Normalizing: \"%s\" <%d,%d> ==> <0..255>\n",
image.hdr.title[0] ? image.hdr.title : "(untitled)", min, max);
bmptr = image.bm;
tail = bmptr+size;
while (bmptr < tail)
{ ch = *bmptr;
if (ch <= min)
{ ch = 0; }
else if (ch >= max)
{ ch = 255; }
else
{ ch = (ch - min) * 255 / (max - min); }
if (ch < 0 || ch > 255)
{ fprintf (stderr, "raw %d, min %d, max %d, out %d\n",
*bmptr, min, max, ch);
}
*bmptr++ = ch;
}
/* The image is now an 8bit per pixel image */
image.hdr.bits = 8;
/* Write it out */
write_bitmap (&image, stdout, outtype);
}
else
{ exit (1); }
exit (0);
}